package controller

// controller/post.go
import (
	"bluebell/logic"
	"bluebell/models"
	"fmt"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"strconv"
	"time"
	// swagger 嵌入文件
)

// GetPostsByKeywordHandler 根据关键字搜索帖子
// @Summary 根据关键字搜索帖子
// @Description 通过关键字搜索帖子(标题或内容)
// @Tags 帖子相关接口
// @Accept application/json
// @Produce application/json
// @Param keyword query string true "搜索关键字"
// @Success 200 {object} models.ResponseSuccess
// @Success 400 {object} models.ResponseError "参数错误"
// @Success 500 {object} models.ResponseError "服务器错误"
// @Router /posts/search [get]
func GetPostsByKeywordHandler(c *gin.Context) {
	// 1. 获取查询参数
	keyword := c.Query("keyword")
	if keyword == "" {
		ResponseError(c, models.CodeInvalidParam)
		return
	}

	// 2. 业务逻辑处理
	data, err := logic.GetPostsByKeyword(keyword)
	if err != nil {
		zap.L().Error("logic.GetPostsByKeyword failed",
			zap.String("keyword", keyword),
			zap.Error(err))
		ResponseError(c, models.CodeServerBusy)
		return
	}

	// 3. 返回响应
	ResponseSuccess(c, data)
}

// CreatePostHandler 创建帖子的处理函数
// @Summary 创建帖子的处理函数
// @Description 创建帖子
// @Tags 帖子相关接口(api分组展示使用的)
// @Accept application/json
// @Produce application/json
// @Param Authorization header string true "Bearer JWT"
// @Param object body models.Post true "帖子信息"
// @Security ApiKeyAuth
// @Success 200 {object} models.ResponseSuccess "成功响应"
// @Success 400 {object} models.ResponseError "响应错误"
// @Success 500 {object} models.ResponseError "服务器错误"
// @Router /post [post]
func CreatePostHandler(c *gin.Context) {
	// 1. 获取参数及参数的校验
	//c.ShouldBindJSON()  // validator --> binding tag
	p := new(models.Post)
	if err := c.ShouldBindJSON(p); err != nil {
		zap.L().Debug("c.ShouldBindJSON(p) error", zap.Any("err", err))
		zap.L().Error("create post with invalid param")
		ResponseError(c, models.CodeInvalidParam)
		return
	}
	if CheckSensitiveWords(p.Content) {
		fmt.Println("有词")
		ResponseError(c, models.CodeSensitiveExist)
		return
	}
	// 从 c 中获取当前用户的 CommentID
	userID, err := getCurrentUserID(c)
	if err != nil {
		// 处理获取用户 CommentID 失败的情况
		// 例如返回登录错误给客户端
		ResponseError(c, models.CodeNeedLogin)
		return
	}
	// 设置帖子的作者 CommentID
	p.AuthorID = userID

	// 2. 创建帖子
	if err := logic.CreatePost(p); err != nil {
		zap.L().Error("logic.CreatePost(p) failed", zap.Error(err))
		ResponseError(c, models.CodeServerBusy)
		return
	}

	// 3. 返回响应
	ResponseSuccess(c, nil)
}

// GetPostDetailHandler 获取帖子详情的处理函数
// @Summary 获取帖子详情的处理函数
// @Description 用id得到帖子
// @Tags 帖子相关接口(api分组展示使用的)
// @Accept application/json
// @Produce application/json
// @Param Authorization header string true "Bearer JWT"
// @Param id path int true "帖子ID"
// @Security ApiKeyAuth
// @Success 200 {object} models.ResponseSuccess "成功响应"
// @Success 400 {object} models.ResponseError "响应错误"
// @Success 500 {object} models.ResponseError "服务器错误"
// @Router /post/:id [get]
func GetPostDetailHandler(c *gin.Context) {
	// 1. 获取参数（从URL中获取帖子的id）
	pidStr := c.Param("id")
	pid, err := strconv.ParseInt(pidStr, 10, 64)
	if err != nil {
		zap.L().Error("get post detail with invalid param", zap.Error(err))
		ResponseError(c, models.CodeInvalidParam)
		return
	}

	// 2. 根据id取出帖子数据（查数据库）
	data, err := logic.GetPostById(pid)
	if err != nil {
		zap.L().Error("logic.GetPostById(pid) failed", zap.Error(err))
		ResponseError(c, models.CodeServerBusy)
		return
	}

	// 新增：用户登录状态下记录观看历史
	currentUserID, getErr := getCurrentUserID(c)

	log := zap.L().With(
		zap.Int64("postID", pid),
		zap.Any("currentUserID", currentUserID),
		zap.Error(getErr),
	)

	log.Info("处理用户观看历史",
		zap.Bool("userLoggedIn", getErr == nil && currentUserID > 0))

	// 只有当用户已登录且没有错误时才记录历史
	if getErr == nil && currentUserID > 0 {
		log := log.With(zap.Int64("userID", currentUserID))

		log.Info("开始记录观看历史")
		startTime := time.Now()

		if err := logic.RecordUserPostHistory(currentUserID, pid); err != nil {
			log.Error("❌ 记录观看历史失败", zap.Error(err))

			// 详细错误日志
			zap.L().Error("历史记录错误详情",
				zap.Int64("userID", currentUserID),
				zap.Int64("postID", pid),
				zap.Error(err),
				zap.String("caller", "GetPostDetailHandler"))
		} else {
			duration := time.Since(startTime)
			log.Info("✅ 成功记录观看历史",
				zap.Duration("duration", duration))

			// 在控制台输出成功信息
			fmt.Println()
			fmt.Println("=====================================")
			fmt.Printf("✅ 历史记录成功: user:%d post:%d\n", currentUserID, pid)
			fmt.Printf("🕒 耗时: %v\n", duration)
			fmt.Println("=====================================")
			fmt.Println()
		}
	} else if getErr != nil {
		log.Info("用户未登录，跳过历史记录")
	} else {
		log.Info("无效用户ID，跳过历史记录")
	}

	// 3. 返回响应
	ResponseSuccess(c, data)
}

// GetPostListHandler 获取帖子列表的处理函数
func GetPostListHandler(c *gin.Context) {
	// 获取分页参数
	page, size := getPageInfo(c)
	// 获取数据
	data, err := logic.GetPostList(page, size)
	if err != nil {
		zap.L().Error("logic.GetPostList() failed", zap.Error(err))
		ResponseError(c, models.CodeServerBusy)
		return
	}
	ResponseSuccess(c, data)
	// 返回响应
}

// GetPostListHandler2 升级版帖子列表接口
// @Summary 升级版帖子列表接口
// @Description 可按社区按时间或分数排序查询帖子列表接口
// @Tags 帖子相关接口(api分组展示使用的)
// @Accept application/json
// @Produce application/json
// @Param Authorization header string true "Bearer JWT"
// @Param object query models.ParamPostList false "查询参数"
// @Security ApiKeyAuth
// @Success 200 {object} models.ResponseSuccess
// @Success 400 {object} models.ResponseError "响应错误"
// @Success 500 {object} models.ResponseError "服务器错误"
// @Router /posts2 [get]
func GetPostListHandler2(c *gin.Context) {
	// GET请求参数(query string)：/api/v1/posts2?page=1&size=10&order=time
	// 初始化结构体时指定初始参数
	p := &models.ParamPostList{
		Page:  1,
		Size:  10,
		Order: models.OrderTime, // magic string
	}
	//c.ShouldBind()  根据请求的数据类型选择相应的方法去获取数据
	//c.ShouldBindJSON() 如果请求中携带的是json格式的数据，才能用这个方法获取到数据
	if err := c.ShouldBindQuery(p); err != nil {
		zap.L().Error("GetPostListHandler2 with invalid params", zap.Error(err))
		ResponseError(c, models.CodeInvalidParam)
		return
	}
	data, err := logic.GetPostListNew(p) // 更新：合二为一
	fmt.Println(data)
	// 获取数据
	if err != nil {
		zap.L().Error("logic.GetPostList() failed", zap.Error(err))
		ResponseError(c, models.CodeServerBusy)
		return
	}
	ResponseSuccess(c, data)
	// 返回响应
}

// PostAvatar 提交头像的处理函数
// @Summary 提交头像的处理函数
// @Description 提交头像地址到数据库
// @Tags 用户相关接口(api分组展示使用的)
// @Accept multipart/form-data
// @Produce application/json
// @Param Authorization header string true "Bearer JWT"
// @Param user_id formData int true "用户ID"
// @Param avatar formData file true "头像文件"
// @Security ApiKeyAuth
// @Success 200 {object} models.ResponseSuccess "成功响应"
// @Success 400 {object} models.ResponseError "响应错误"
// @Success 500 {object} models.ResponseError "服务器错误"
// @Router /user/:user_id/avatar [post]
func PostAvatar(c *gin.Context) {
	// 获取参数，id与file
	userID := c.PostForm("user_id")
	file, err := c.FormFile("avatar")
	if err != nil {
		ResponseError(c, models.CodeInvalidParam)
		zap.Error(err)
	}
	// 传递参数到logic层
	logic.PostAvatar(c, userID, file)
	ResponseSuccess(c, nil)
}

// PostTop 置顶帖子功能实现
func PostTop(c *gin.Context) {

}

// GetPostBySelect 使用查询拿到帖子
// @Summary 使用查询拿到帖子
// @Description 用帖子标题得到帖子
// @Tags 帖子相关接口(api分组展示使用的)
// @Accept application/json
// @Produce application/json
// @Param Authorization header string true "Bearer JWT"
// @Param title path string true "帖子标题"
// @Security ApiKeyAuth
// @Success 200 {object} models.ResponseSuccess "成功响应"
// @Success 400 {object} models.ResponseError "响应错误"
// @Success 500 {object} models.ResponseError "服务器错误"
// @Router /select/name [get]
func GetPostBySelect(c *gin.Context) {
	title := c.Query("title")
	if title == "" {
		ResponseError(c, models.CodeInvalidParam)
		return
	}
	post, err := logic.GetPostByTitle(title)
	if err != nil {
		ResponseError(c, models.CodeInvalidParam)
		return
	}
	ResponseSuccess(c, post)
}
